﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using Sicurezza.CA.DataProvider;
using Sicurezza.CA.Entita;
using OpenSSL.X509;
using Sicurezza.Entita;

namespace Sicurezza.CA.Manager
{
    public class RequestManager
    {
        private static RequestDataProvider dataProvider = new RequestDataProvider();

        public static List<Request> GetAll()
        {
            return dataProvider.GetAll();
            
        }

        public static List<Request> GetWaiting()
        {
            return dataProvider.GetWaiting();
        }

        public static void Accept(string ReqId,int days)
        {
            SSLManager.CreateCertificate(Convert.ToInt32(ReqId), days);
            dataProvider.SetState(Convert.ToInt32(ReqId.Replace("req-","")),RequestState.Accepted);
        }

        public static void Reject(string ReqId, string reason)
        {
            dataProvider.SetState(Convert.ToInt32(ReqId.Replace("req-", "")),RequestState.Refused, reason.Replace("'","''"));
        }

        public static string Get(string ReqId)
        {
            string req = FileManager.LoadRequest(Convert.ToInt32(ReqId));
            X509Request r = new X509Request(req);
            return r.ToString();

        }

        public static string Save(string request)
        {

            RequestState rs = RequestState.Waiting;
            string reason = "";
            int ReqId = 0;
            X509Request r = new X509Request(request);
            
            
            int ProfileId = ProfileManager.GetId(r.Subject);

            //-- Se non esiste il profile in database, lo creo
            //-- inoltre sono sicuro che non ho già emesso un certificato verso
            //-- questo DN
            //-- In caso contrario, verifico che un certificato con le stesse 
            //-- caratteristiche esista già: in caso affermativo, rifiuto la richiesta
            if (ProfileId == 0)
                ProfileId = ProfileManager.Save(r.Subject);
            else
            {
                if (SSLManager.Exist(r.Subject, ProfileId))
                {
                    rs = RequestState.Refused;
                    reason = "A certificate with similar attributes already exist.";
                }
            }

            //-- Controllo che la firma coincida con la chiave pubblica
            if (!r.Verify(r.PublicKey))
            {
                rs = RequestState.Refused;
                reason = "The signature does not match with the supplied key.";
            }

            ReqId = dataProvider.Save(r, ProfileId,rs,reason);
            FileManager.SaveRequest(ReqId, r);
            return "req-" + ReqId;

        }

        public static string Check(string ReqId)
        {
            return dataProvider.Check(int.Parse(ReqId.Replace("req-","")));
        }
    }
}
